package com.nl.util;

import java.sql.Connection;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.pool.DruidDataSource;


public final class ConnectionManager {
	
	private static final Logger log = LoggerFactory.getLogger(ConnectionManager.class);
	
	private DruidDataSource dataSource = null;
	
	private ConnectionManager() {
		initDataSourse();
		log.info("Initialize database connection pool.......");
	}
	
	private void initDataSourse() {
		dataSource = new DruidDataSource();
		dataSource.setDriverClassName(ConfigUtils.getInstance().getValue("jdbcDriverClassName"));
		dataSource.setUrl(ConfigUtils.getInstance().getValue("jdbcUrl")); 
		dataSource.setUsername(ConfigUtils.getInstance().getValue("jdbcUsername")); 
		dataSource.setPassword(ConfigUtils.getInstance().getValue("jdbcPassword"));
		
		// ��ʼ��ʱ��ȡ5������
		dataSource.setInitialSize(Integer.parseInt(ConfigUtils.getInstance().getValue("minIdle"))); 
		// ���ӳ��б�������С������
		dataSource.setMinIdle(Integer.parseInt(ConfigUtils.getInstance().getValue("minIdle"))); 
		// ���ӳ��б��������������
		dataSource.setMaxActive(Integer.parseInt(ConfigUtils.getInstance().getValue("maxActive")));
		// ���û�ȡ���ӵȴ���ʱ��ʱ�� 
		dataSource.setMaxWait(60000);
		// ���ü����òŽ���һ�μ�⣬�����Ҫ�رյĿ������ӣ���λ�Ǻ���
		dataSource.setTimeBetweenEvictionRunsMillis(60000);
		// ����һ�������ڳ�����С�����ʱ�䣬��λ�Ǻ���
		dataSource.setMinEvictableIdleTimeMillis(300000);
		dataSource.setRemoveAbandoned(true);
		dataSource.setRemoveAbandonedTimeout(300);
		dataSource.setLogAbandoned(false);
		// ������������Ƿ���Ч��sql
		dataSource.setValidationQuery("select 1 from dual");
		// ��������ʱִ��validationQuery��������Ƿ���Ч������������ûή�����ܡ�
		dataSource.setTestOnBorrow(true);
		// �黹����ʱִ��validationQuery��������Ƿ���Ч������������ûή������
		dataSource.setTestOnReturn(false);
		// ����ʱ�����timeBetweenEvictionRunsMillis�Ż��������Ƿ���Ч
		dataSource.setTestWhileIdle(true);
		
		// ��PSCache������ָ��ÿ��������PSCache�Ĵ�С
		dataSource.setPoolPreparedStatements(true);
		dataSource.setMaxPoolPreparedStatementPerConnectionSize(100);
	}
	
    private static class SingletonHolder {        
        private static final ConnectionManager instance = new ConnectionManager();        
    }    

	public static ConnectionManager getInstance() {
		return SingletonHolder.instance;
	}
	
	public synchronized Connection getConnection() throws SQLException {
		return dataSource.getConnection();
	}
}
